package service

import (
	"errors"
	"fmt"
	"github.com/vueadmin/app/admin/dto"
	"github.com/vueadmin/app/admin/model"
	"github.com/vueadmin/app/admin/vo"
	"github.com/vueadmin/global"
	"github.com/vueadmin/pkg/crontab"
	"github.com/vueadmin/utils/conv"
)

var AdminCrontabService = new(adminCrontab)

type adminCrontab struct{}

/**
 * @description(数据列表)
 * @buildcode(true)
 */
func (p adminCrontab) GetPageList(req *dto.AdminCrontabPageReq) ([]*vo.AdminCrontabList, int64, error) {
	var (
		entity model.AdminCrontab
		list   []*vo.AdminCrontabList
		count  int64
	)
	query := global.DB.Model(&entity)
	if !conv.IsEmpty(req.CrontabId) {
		query = query.Where("crontab_id = ?", req.CrontabId)
	}
	if !conv.IsEmpty(req.Name) {
		query = query.Where("name LIKE ?", "%"+req.Name+"%")
	}
	if !conv.IsEmpty(req.Type) {
		query = query.Where("type = ?", req.Type)
	}
	if !conv.IsEmpty(req.Status) {
		query = query.Where("status = ?", req.Status)
	}
	order := "crontab_id desc"
	if !conv.IsEmpty(req.Sort) && !conv.IsEmpty(req.Order) {
		order = fmt.Sprintf("%s %s", req.Sort, req.Order)
	}
	if err := query.Limit(req.Limit).Offset((req.Page - 1) * req.Limit).Order(order).Find(&list).Error; err != nil {
		return nil, 0, err
	}
	query.Count(&count)

	return list, count, nil
}

/**
 * @description(修改排序开关)
 * @buildcode(false)
 */
func (p adminCrontab) UpdateExt(req map[string]interface{}) error {
	entity := model.AdminCrontab{}
	if err := global.DB.Where("crontab_id = ?", req["crontab_id"]).Limit(1).First(&entity).Error; err != nil {
		return err
	}
	if conv.Int8(req["status"]) == 0 {
		crontab.Stop(entity.CrontabId)
	} else {
		if entity.Type == 1 {
			crontab.Start(entity.Target, entity.Type, entity.Rule, entity.CrontabId)
		} else {
			if crontab.IsExistFunc(entity.Target) {
				crontab.Start(entity.Target, entity.Type, entity.Rule, entity.CrontabId)
			} else {
				return errors.New("定时任务方法不存在，请检查配置文件是否定义!")
			}
		}
	}
	if err := global.DB.Model(&entity).Where("crontab_id", req["crontab_id"]).Updates(req).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(添加)
 * @buildcode(true)
 */
func (p adminCrontab) Add(req *dto.AdminCrontabAddReq) (uint, error) {
	entity := model.AdminCrontab{}
	entity.Name = req.Name
	entity.Type = req.Type
	entity.Rule = req.Rule
	entity.Status = req.Status
	entity.Target = req.Target
	entity.Remark = req.Remark

	if err := global.DB.Create(&entity).Error; err != nil {
		return 0, err
	}
	return entity.CrontabId, nil
}

/**
 * @description(修改)
 * @buildcode(false)
 */
func (p adminCrontab) Update(req *dto.AdminCrontabUpdateReq) error {
	entity := model.AdminCrontab{
		CrontabId: req.CrontabId,
	}
	if err := global.DB.Limit(1).First(&entity).Error; err != nil {
		return err
	}
	entity.Name = req.Name
	entity.Type = req.Type
	entity.Rule = req.Rule
	entity.Target = req.Target
	entity.Remark = req.Remark
	//判断定时任务执行方法 ，定时任务存在 并且状态是开启的情况下先执行停止 在执行启动

	if entity.Type == 1 {
		if entity.Status == 1 {
			if crontab.IsExistCron(entity.CrontabId) {
				crontab.Stop(entity.CrontabId)
			}
			crontab.Start(entity.Target, entity.Type, entity.Rule, entity.CrontabId)
		}
	} else {
		if crontab.IsExistFunc(entity.Target) && entity.Status == 1 {
			if crontab.IsExistCron(entity.CrontabId) {
				crontab.Stop(entity.CrontabId)
			}
			crontab.Start(entity.Target, entity.Type, entity.Rule, entity.CrontabId)
		} else {
			return errors.New("定时任务不存在，请检查配置文件是否定义!")
		}
	}

	field := conv.StringToSlice("name,type,rule,target,remark", ",")
	if err := global.DB.Select(field).Updates(&entity).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(获取修改详情)
 * @buildcode(true)
 */
func (p adminCrontab) GetUpdateInfo(req *dto.AdminCrontabGetUpdateInfoReq) (*model.AdminCrontab, error) {
	entity := model.AdminCrontab{}
	if err := global.DB.Where("crontab_id = ?", req.CrontabId).Limit(1).First(&entity).Error; err != nil {
		return nil, err
	}
	return &entity, nil
}

/**
 * @description(删除)
 * @buildcode(false)
 */
func (p adminCrontab) Delete(req *dto.AdminCrontabDeleteReq) error {
	ids := conv.Slice(req.CrontabId)
	if len(ids) > 1 {
		return errors.New("禁止批量删除!")
	}
	var info vo.AdminCrontabDetail
	query := global.DB.Model(&model.AdminCrontab{}).Where("crontab_id = ?", req.CrontabId)
	if err := query.Limit(1).First(&info).Error; err != nil {
		return err
	}
	if err := query.Delete(true).Error; err != nil {
		return err
	}
	if info.Status == 1 && crontab.IsExistCron(conv.Uint(req.CrontabId)) {
		crontab.Stop(conv.Uint(req.CrontabId))
	}
	return nil
}

/**
 * @description(查看详情)
 * @buildcode(true)
 */
func (p adminCrontab) Detail(req *dto.AdminCrontabDetailReq) (*vo.AdminCrontabDetail, error) {
	var info vo.AdminCrontabDetail
	query := global.DB.Model(&model.AdminCrontab{})
	if err := query.Where("crontab_id = ?", req.CrontabId).Limit(1).First(&info).Error; err != nil {
		return nil, err
	}
	return &info, nil
}
